﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using OAclient.Models;
using ServiceApplication.Service.WorkFlow;
using System.Workflow.Runtime;
using System.Data;
using System.Workflow.Activities;
using System.IO;
using System.Xml;
using Bukovics.Workflow.Hosting;
using System.Workflow.Runtime.Hosting;
using OAclient.Common;

namespace OAclient
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Login", action = "LogOn", id = UrlParameter.Optional } // Parameter defaults
                //new { controller = "Notify", action = "NotifyPartial", id = UrlParameter.Optional } // Parameter defaults
            );
        }

        static WorkFlowService workflowService = new WorkFlowService();
        protected void Application_Start(object sender, EventArgs e)
        {
            AreaRegistration.RegisterAllAreas();
            RegisterRoutes(RouteTable.Routes);

            ModelBinders.Binders.Add(typeof(UserModel), new UserModelBinder());

            var storUrl = ComVariable.StoreUrl;
            if (!Directory.Exists(storUrl))
            {
                var sysUrl = Path.Combine(storUrl, "System");
                Directory.CreateDirectory(sysUrl);
                Directory.CreateDirectory(Path.Combine(storUrl, "webstore"));
                var fileName = Path.Combine(Path.Combine(Directory.GetParent(ComVariable.BaseUrl).FullName, "images"), "HeadImg.jpg");
                File.Copy(fileName, Path.Combine(sysUrl, "HeadImg.jpg"));
            }

            Console.WriteLine("Application_Start:");
            WorkflowRuntimeManager workflowRuntimeManager = new WorkflowRuntimeManager(new System.Workflow.Runtime.WorkflowRuntime());
            //add services to the workflow runtime
            AddServices(workflowRuntimeManager.WorkflowRuntime);
            Application[MyWorkHelpr.WorkflowRuntimeManager] = workflowRuntimeManager;

            workflowRuntimeManager.WorkflowRuntime.WorkflowCreated
                += new EventHandler<System.Workflow.Runtime.WorkflowEventArgs>(WorkflowRuntime_WorkflowCreated);
            workflowRuntimeManager.WorkflowRuntime.WorkflowCompleted
                += new EventHandler<System.Workflow.Runtime.WorkflowCompletedEventArgs>(WorkflowRuntime_WorkflowCompleted);
            workflowRuntimeManager.WorkflowRuntime.WorkflowPersisted
                += new EventHandler<System.Workflow.Runtime.WorkflowEventArgs>(WorkflowRuntime_WorkflowPersisted);
            workflowRuntimeManager.WorkflowRuntime.WorkflowUnloaded
                += new EventHandler<System.Workflow.Runtime.WorkflowEventArgs>(WorkflowRuntime_WorkflowUnloaded);
            workflowRuntimeManager.WorkflowRuntime.WorkflowLoaded
                += new EventHandler<System.Workflow.Runtime.WorkflowEventArgs>(WorkflowRuntime_WorkflowLoaded);
            workflowRuntimeManager.WorkflowRuntime.WorkflowIdled
                += new EventHandler<System.Workflow.Runtime.WorkflowEventArgs>(WorkflowRuntime_WorkflowIdled);

            Application[MyWorkHelpr.WorkflowStaticTemplate] = workflowService.QueryPlateList(workflowRuntimeManager);
            //start the runtime prior to checking for any
            //existing workflows that have been persisted
            workflowRuntimeManager.WorkflowRuntime.StartRuntime();
            #region 添加静态工作流模板
            //改成实时获取
            //WorkflowInstance ins = null;
            //DataTable dt = workflowService.QueryWfTemplate();
            //Application[MyWorkHelpr.WorkflowStaticTemplate] = new Dictionary<int, StateMachineWorkflowInstance>();
            //StateMachineWorkflowInstance stateMachineWorkflowInstance = null;
            //for (int i = 0; i < dt.Rows.Count; i++)
            //{
            //    int wftemplate_id = int.Parse(dt.Rows[i][0].ToString());
            //    TextReader t1 = new StringReader(dt.Rows[i][2].ToString());
            //    TextReader t2 = new StringReader(dt.Rows[i][3].ToString());
            //    XmlReader define = XmlReader.Create(t1);
            //    XmlReader rule = XmlReader.Create(t2);
            //    ins = workflowRuntimeManager.WorkflowRuntime.CreateWorkflow(define, rule, null);
            //    stateMachineWorkflowInstance = new
            //         StateMachineWorkflowInstance(workflowRuntimeManager.WorkflowRuntime, ins.InstanceId);
            //    (Application[MyWorkHelpr.WorkflowStaticTemplate] as Dictionary<int, StateMachineWorkflowInstance>).Add(wftemplate_id, stateMachineWorkflowInstance);
            //}


            #endregion
        }

        void WorkflowRuntime_WorkflowCompleted(object sender, System.Workflow.Runtime.WorkflowCompletedEventArgs e)
        {
            UpdateCompletedWorkflow(e.WorkflowInstance.InstanceId);
            UpdateDisplay(e.WorkflowInstance.InstanceId, "Completed");
        }

        #region Workflow event handling

        void WorkflowRuntime_WorkflowCreated(object sender, System.Workflow.Runtime.WorkflowEventArgs e)
        {
            UpdateDisplay(e.WorkflowInstance.InstanceId, "Created");
        }

        void WorkflowRuntime_WorkflowIdled(object sender, System.Workflow.Runtime.WorkflowEventArgs e)
        {
            UpdateDisplay(e.WorkflowInstance.InstanceId, "Idled");
        }

        void WorkflowRuntime_WorkflowLoaded(object sender,
            System.Workflow.Runtime.WorkflowEventArgs e)
        {
            UpdateDisplay(e.WorkflowInstance.InstanceId, "Loaded");
        }

        void WorkflowRuntime_WorkflowUnloaded(object sender,
            System.Workflow.Runtime.WorkflowEventArgs e)
        {
            UpdateDisplay(e.WorkflowInstance.InstanceId, "Unloaded");
        }

        void WorkflowRuntime_WorkflowPersisted(object sender,
            System.Workflow.Runtime.WorkflowEventArgs e)
        {
            UpdateDisplay(e.WorkflowInstance.InstanceId, "Persisted");
        }

        private delegate void UpdateDelegate();

        private void UpdateDisplay(Guid instanceId, String statusMessage)
        {
            //UpdateDelegate theDelegate = delegate()
            //{
            //    Workflow workflow = GetWorkflow(instanceId);
            //    workflow.StatusMessage = statusMessage;
            //    //RefreshData();
            //    //slow things down so you can see the status changes
            //    System.Threading.Thread.Sleep(1000);
            //};

            ////execute the anonymous delegate on the UI thread
            //this.Invoke(theDelegate);
            Workflow workflow = GetWorkflow(instanceId);
            workflow.StatusMessage = statusMessage;
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("{0} is {1}", instanceId, statusMessage);
        }
        private void UpdateCompletedWorkflow(Guid instanceId)
        {
            //UpdateDelegate theDelegate = delegate()
            //{
            //    Workflow workflow = GetWorkflow(instanceId);
            //    workflow.IsCompleted = true;
            //};       

            ////execute the anonymous delegate on the UI thread
            //this.Invoke(theDelegate);
            try
            {
                var wfrManager = Application[MyWorkHelpr.WorkflowRuntimeManager] as WorkflowRuntimeManager;
                StateMachineWorkflowInstance stateInstance = new StateMachineWorkflowInstance(wfrManager.WorkflowRuntime, instanceId);
                stateInstance.WorkflowInstance.Terminate("静态模板卸载");
            }
            catch { }
        }

        private Workflow GetWorkflow(Guid instanceId)
        {
            Workflow result = null;
            if (MyWorkHelpr._workflows.ContainsKey(instanceId))
            {
                result = MyWorkHelpr._workflows[instanceId];
            }
            else
            {
                //create a new instance
                result = new Workflow();
                result.InstanceId = instanceId;
                MyWorkHelpr._workflows.Add(result.InstanceId, result);
            }
            return result;
        }
        #endregion

        /// <summary>
        /// Add any services needed by the runtime engine
        /// </summary>
        /// <param name="instance"></param>4
        private void AddServices(System.Workflow.Runtime.WorkflowRuntime instance)
        {
            ////use the standard SQL Server persistence service
            String connStringPersistence = String.Format(
                "Initial Catalog={0};Data Source={1};Integrated Security={2};",
                "SqlPersistenceService", @".\SQL2005", "SSPI");// \SQL2005
            MyWorkHelpr._persistence = new SqlWorkflowPersistenceService(
                connStringPersistence, true, new TimeSpan(0, 2, 0), new TimeSpan(0, 0, 5));
            instance.AddService(MyWorkHelpr._persistence);

            //add the external data exchange service to the runtime
            ExternalDataExchangeService exchangeService = new ExternalDataExchangeService();
            instance.AddService(exchangeService);

            //add our local service 
            MyWorkHelpr._billServer = new BillServer();
            exchangeService.AddService(MyWorkHelpr._billServer);
        }


        protected void Session_Start(object sender, EventArgs e)
        {

        }

        protected void Application_BeginRequest(object sender, EventArgs e)
        {

        }

        protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {

        }

        protected void Application_Error(object sender, EventArgs e)
        {

        }

        protected void Session_End(object sender, EventArgs e)
        {
        }

        protected void Application_End(object sender, EventArgs e)
        {
            //所有静态工作流实例在网站关闭前都要销毁
            var platelist = Application[MyWorkHelpr.WorkflowStaticTemplate] as Dictionary<int, StateMachineWorkflowInstance>;
            foreach (var item in platelist)
            {
                UpdateCompletedWorkflow(item.Value.InstanceId);
            }
            WorkflowRuntimeManager workflowRuntimeManager = Application[MyWorkHelpr.WorkflowRuntimeManager] as WorkflowRuntimeManager;
            workflowRuntimeManager.WorkflowRuntime.StopRuntime();

            WorkFlowService wfs = new WorkFlowService();
            wfs.PersistenceInstanceClear();
        }


    }
}